package com.to8to.kitt.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

/**
 * 对日期进行操作的一些帮助类
 * 
 * @author tom
 * @time 2008-12-5
 */
@SuppressWarnings("deprecation")
public class DateUtil {
	public static Date add(Date dateFrom, int field, int amount) {
		Calendar cd = Calendar.getInstance();
		cd.setTime(dateFrom);
		cd.add(field, amount);
		return cd.getTime();
	}

	public static String addDays(String date, int days) {
		return addDays(date, days, "yyyy-MM-dd");
	}

	public static String addDays(String date, int days, String format) {
		try {
			Calendar cal = Calendar.getInstance();
			cal.setTime(parse(date, format));
			cal.add(GregorianCalendar.DATE, days);
			return format(cal.getTime(), format);
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 把date1的小时，分钟，秒换成date2的小时，分钟，秒,返回换值后的date1
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static Date changeTheHourMinuteSecond(Date date1, Date date2) {
		Calendar cl1 = Calendar.getInstance();
		cl1.setTime(date1);
		cl1.set(Calendar.HOUR_OF_DAY, 0);
		cl1.set(Calendar.MINUTE, 0);
		cl1.set(Calendar.SECOND, 0);
		Calendar cl2 = Calendar.getInstance();
		cl2.setTime(date2);
		cl1.set(Calendar.HOUR_OF_DAY, cl2.get(Calendar.HOUR_OF_DAY));
		cl1.set(Calendar.MINUTE, cl2.get(Calendar.MINUTE));
		cl1.set(Calendar.SECOND, cl2.get(Calendar.SECOND));
		return cl1.getTime();
	}

	/**
	 * 得到两个日期间的天数
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static long dateDiff(Date start, Date end) {
		long inter = end.getTime() - start.getTime();
		if (inter < 0) {
			return 0;
		}
		long dateMillSec = 24 * 60 * 60 * 1000;
		long dateCnt = inter / dateMillSec;
		long remainder = inter % dateMillSec;
		if (remainder != 0) {
			dateCnt++;
		}
		return dateCnt;
	}

	public static String format(Date date) {
		return format(date, "yyyy-MM-dd HH:mm:ss");
	}

	public static String format(Date date, String format) {
		try {
			if (format != null && !"".equals(format) && date != null) {
				SimpleDateFormat formatter = new SimpleDateFormat(format);
				return formatter.format(date);
			}
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 将Date转换为String
	 * 
	 * @param d
	 * @return
	 */
	public static String formatDate(Date d) {
		if (d == null) {
			return null;
		}
		try {
			return new SimpleDateFormat("yyyy-MM-dd").format(d);
		} catch (Exception e) {
			return null;
		}
	}

	public static String formatDateToDetail(Date d) {
		if (d == null) {
			return null;
		}
		try {
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d);
		} catch (Exception e) {
			return null;
		}
	}

	public static String formatDateYyyyMmDd(Date date) {
		try {
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
			return formatter.format(date);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 得到本周第一天日期
	 * 
	 * @author vincent.shan
	 * @return
	 */
	public static Date getCurrentWeekMonday() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		int index = cal.get(Calendar.DAY_OF_WEEK);
		// 转成中国的习惯,如果是第一天,则转化为第七天(星期天外国为一周的第一天,而中国为每周的最后一天)
		if (index == 1) {
			index = 8;
		}
		cal.add(Calendar.DATE, -(index - 2));
		return cal.getTime();
	}

	/**
	 * 得到本周最后一天的日期
	 * 
	 * @author vincent.shan
	 * @return
	 */
	public static Date getCurrentWeekSaturday() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		int index = cal.get(Calendar.DAY_OF_WEEK);
		if (index == 1) {
			index = 8;
		}
		cal.add(Calendar.DATE, -(index - 2));
		cal.add(Calendar.DATE, 6);
		return cal.getTime();
	}

	/**
	 * 取出一个月中某天的日期
	 * 
	 * @param month
	 * @param num
	 * @return
	 */
	public static Date getDateOfMonthByNum(String month, int num) {
		Calendar cl = Calendar.getInstance();
		cl.setTime(parseDateyyyyMM(month));
		cl.set(Calendar.HOUR_OF_DAY, 0);
		cl.set(Calendar.MINUTE, 0);
		cl.set(Calendar.SECOND, 0);
		cl.set(Calendar.MILLISECOND, 0);
		cl.add(Calendar.DAY_OF_YEAR, num - 1);
		return cl.getTime();
	}

	/**
	 * 得到yyyyMM的年月
	 * 
	 * @param date
	 * @return
	 */
	public static String getDateyyyyMM(Date date) {
		return new SimpleDateFormat("yyyyMM").format(date);
	}

	/**
	 * 得到yyyyMM的年月
	 * 
	 * @param date
	 * @return
	 */
	public static String getDateyyyyMMdd(Date date) {
		return new SimpleDateFormat("yyyyMMdd").format(date);
	}

	/**
	 * 根据两个日期，算出某个月份的第一天，或者最后一天
	 * 
	 * @param dateFrom
	 * @param dateTo
	 * @param month
	 * @param flag
	 * @return
	 */
	public static int getDayBetweenDateStartOrEnd(Date dateFrom, Date dateTo, Date month, String flag) {
		if (dateFrom.getTime() > dateTo.getTime()) {
			Date temp = dateFrom;
			dateFrom = dateTo;
			dateTo = temp;
		}
		if (getDateyyyyMM(month).compareTo(getDateyyyyMM(dateFrom)) > 0 && getDateyyyyMM(month).compareTo(getDateyyyyMM(dateTo)) < 0) {
			return "start".equals(flag) ? 1 : getMonthsMaxDay(month);
		} else if (getDateyyyyMM(month).compareTo(getDateyyyyMM(dateFrom)) == 0 && getDateyyyyMM(month).compareTo(getDateyyyyMM(dateTo)) < 0) {
			return "start".equals(flag) ? getDayOfMonth(dateFrom) : getMonthsMaxDay(month);
		} else if (getDateyyyyMM(month).compareTo(getDateyyyyMM(dateFrom)) > 0 && getDateyyyyMM(month).compareTo(getDateyyyyMM(dateTo)) == 0) {
			return "start".equals(flag) ? 1 : getDayOfMonth(dateTo);
		} else {
			return "start".equals(flag) ? getDayOfMonth(dateFrom) : getDayOfMonth(dateTo);
		}
	}

	/**
	 * 根据一个日期，算出是这个月中的第几天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfMonth(Date date) {
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date);
		return cal1.get(Calendar.DAY_OF_MONTH);
	}

	public static int getDayofWeek(Date date, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + day - 1);
		return calendar.get(Calendar.DAY_OF_WEEK);
	}

	public static String getDaysBetweenTwoDates(String dateFrom, String dateEnd) {
		Date dtFrom = null;
		Date dtEnd = null;
		dtFrom = string2Date(dateFrom, "yyyy-MM-dd");
		dtEnd = string2Date(dateEnd, "yyyy-MM-dd");
		long begin = dtFrom.getTime();
		long end = dtEnd.getTime();
		long inter = end - begin;
		if (inter < 0) {
			inter = inter * (-1);
		}
		long dateMillSec = 24 * 60 * 60 * 1000;
		long dateCnt = inter / dateMillSec;
		long remainder = inter % dateMillSec;
		if (remainder != 0) {
			dateCnt++;
		}
		return String.valueOf(dateCnt);
	}

	public static long getDaysBetweenTwoDatesMath(String dateFrom, String dateEnd) {
		Date dtFrom = null;
		Date dtEnd = null;
		dtFrom = string2Date(dateFrom, "yyyy-MM-dd");
		dtEnd = string2Date(dateEnd, "yyyy-MM-dd");
		long begin = dtFrom.getTime();
		long end = dtEnd.getTime();
		long inter = end - begin;
		long dateMillSec = 24 * 60 * 60 * 1000;
		long dateCnt = inter / dateMillSec;
		long remainder = inter % dateMillSec;
		if (remainder != 0) {
			dateCnt++;
		}
		return dateCnt;
	}

	/**
	 * 功能：取得两个日期中最大的日期,如果两个日期参数都为null则返回null
	 * 
	 * @author irvshan
	 * @param date1
	 * @param date2
	 * @return Date or null
	 */
	public static Date getMaxmizeDate(Date date1, Date date2) {
		if (date1 == null) {
			return date2;
		} else if (date2 == null) {
			return date1;
		} else if (date1.compareTo(date2) < 0) {
			return date2;
		}
		return date1;
	}

	/**
	 * 功能：取得两个日期中最小的日期,如果两个日期参数都为null则返回null
	 * 
	 * @author irvshan
	 * @param date1
	 * @param date2
	 * @return Date or null
	 */
	public static Date getMinimizeDate(Date date1, Date date2) {
		if (date1 == null) {
			return date2;
		} else if (date2 == null) {
			return date1;
		} else if (date1.compareTo(date2) > 0) {
			return date2;
		}
		return date1;
	}

	/**
	 * 算出两个日期中所包含的月份
	 * 
	 * @param fromDate
	 * @param toDate
	 * @return
	 */
	public static Set<String> getMonthBetweenTwoDate(Date fromDate, Date toDate) {
		long begin = fromDate.getTime();
		long end = toDate.getTime();
		long inter = end - begin;
		if (inter < 0) {
			inter = inter * (-1);
		}
		long dateMillSec = 86400000;
		long dateCnt = inter / dateMillSec;
		long remainder = inter % dateMillSec;
		if (remainder != 0) {
			dateCnt++;
		}
		Set<String> set = new LinkedHashSet<String>();
		Calendar cl = Calendar.getInstance();
		cl.setTime(fromDate);
		cl.set(Calendar.HOUR_OF_DAY, 0);
		cl.set(Calendar.MINUTE, 0);
		cl.set(Calendar.SECOND, 0);
		cl.set(Calendar.MILLISECOND, 0);
		set.add(getDateyyyyMM(cl.getTime()));
		for (int i = 1; i <= dateCnt; i++) {
			cl.add(Calendar.DAY_OF_YEAR, 1);
			set.add(getDateyyyyMM(cl.getTime()));
		}
		return set;
	}

	/**
	 * 根据某个日期，返回本月第一天
	 * 
	 * @param date
	 *            任何一天
	 * @return Date 当月第一天
	 */
	public static Date getMonthsFirstDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 根据某个日期，返回本月最后一天
	 * 
	 * @param date
	 *            任何一天
	 * @return Date 当月第一天
	 */
	public static Date getMonthsLastDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		cal.add(Calendar.MONTH, 1);
		cal.add(Calendar.DATE, -1);
		return cal.getTime();
	}

	/**
	 * 得到一月的最大天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonthsMaxDay(Date date) {
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date);
		return cal1.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 从当天日期移动一定的月数
	 * 
	 * @param month
	 * @return
	 */
	public static Date getMoveMonthDate(int month) {
		Calendar cl = Calendar.getInstance();
		// cl.setTime(nowDate);
		Date nowDate = new Date();
		cl.set(nowDate.getYear() + 1900, nowDate.getMonth(), nowDate.getDate(), 0, 0, 0);
		cl.add(Calendar.MONDAY, month);
		return cl.getTime();
	}

	public static int getWeekByDate(Date date) {
		Calendar cl1 = Calendar.getInstance();
		cl1.setTime(date);
		cl1.set(Calendar.HOUR_OF_DAY, 0);
		cl1.set(Calendar.MINUTE, 0);
		cl1.set(Calendar.SECOND, 0);
		return cl1.get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 得到昨天
	 * 
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date getYesterday() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		cal.add(Calendar.DAY_OF_MONTH, -1);
		return cal.getTime();
	}

	/**
	 * 判断时间是否是凌晨,默认当前系统时间
	 * 
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static boolean isDawn(Date date) throws Exception {
		boolean isDawn = false;
		Calendar tempCal = Calendar.getInstance();
		if (date != null) {
			tempCal.setTime(date);
		}
		int hour = tempCal.get(Calendar.HOUR_OF_DAY);
		if (0 <= hour && hour <= 6) {
			isDawn = true;
		}
		return isDawn;
	}

	public static List<String> listDates(String startdate, String enddate, String format) {
		List<String> dates = new LinkedList<String>();
		SimpleDateFormat sformat = new SimpleDateFormat(format);
		try {
			Date date1 = sformat.parse(startdate);
			Date date2 = sformat.parse(enddate);
			Calendar start = Calendar.getInstance();
			start.setTime(date1);
			Calendar end = Calendar.getInstance();
			end.setTime(date2);
			while (start.compareTo(end) <= 0) {
				String tmp = sformat.format(start.getTime());
				dates.add(tmp);
				start.set(Calendar.DATE, start.get(Calendar.DATE) + 1);
			}
			return dates;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static List<Date> listDates(Date date1, Date date2) {
		List<Date> dates = new LinkedList<Date>();
		Calendar start = Calendar.getInstance();
		start.setTime(date1);
		Calendar end = Calendar.getInstance();
		end.setTime(date2);
		while (start.compareTo(end) <= 0) 
		{
			dates.add(start.getTime());
			start.set(Calendar.DATE, start.get(Calendar.DATE) + 1);
		}
		return dates;
	}
	

	public static List<String> listMonth(String startdate, String enddate, String format) {
		List<String> dates = new LinkedList<String>();
		SimpleDateFormat sformat = new SimpleDateFormat(format);
		try {
			Date date1 = sformat.parse(startdate);
			Date date2 = sformat.parse(enddate);
			Calendar start = Calendar.getInstance();
			start.setTime(date1);
			Calendar end = Calendar.getInstance();
			end.setTime(date2);
			while (start.compareTo(end) <= 0) {
				String tmp = sformat.format(start.getTime());
				dates.add(tmp);
				start.set(Calendar.MONTH, start.get(Calendar.MONTH) + 1);
			}
			return dates;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}



	/**
	 * 从指定日期移动一定的天数
	 * 
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date moveDay(Date date, int day) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		cal.add(Calendar.DAY_OF_MONTH, day);
		return cal.getTime();
	}

	public static String normDate(String input, String iformat) {
		return normDate(input, iformat, Locale.US, "yyyy-MM-dd HH:mm:ss");
	}

	public static String normDate(String input, String iformat, Locale local, String oformat) {
		if (StringUtils.isEmpty(input)) {
			return null;
		}
		Date date = DateUtil.parse(input, iformat, local);
		return date == null ? input : DateUtil.format(date, oformat);
	}

	public static String normDate(String input, String iformat, String oformat) {
		return normDate(input, iformat, Locale.US, oformat);
	}

	public static Date parse(String text) {
		return parse(text, "yyyy-MM-dd HH:mm:ss");
	}

	public static Date parse(String text, String format) {
		return parse(text, format, Locale.US);
	}

	public static Date parse(String text, String format, Locale local) {
		try {
			if (format != null && !"".equals(format) && text != null) {
				SimpleDateFormat formatter = new SimpleDateFormat(format, local);
				return formatter.parse(text);
			}
		} catch (Exception e) {
		}
		return null;
	}

	public static Date parseDateyyyyMM(String month) {
		try {
			return new SimpleDateFormat("yyyyMM").parse(month);
		} catch (ParseException e) {
			return null;
		}
	}

	public static Date parseDateyyyyMMdd(String date) {
		try {
			return new SimpleDateFormat("yyyyMMdd").parse(date);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 把日期字符串格式化为日期类型
	 * 
	 * @param datetext
	 *            日期字符串
	 * @param format
	 *            日期格式，如果不传则使用"yyyy-MM-dd HH:mm:ss"格式
	 * @return
	 */
	public static Date string2Date(String datetext, String format) {
		try {
			SimpleDateFormat df;
			if (datetext == null || "".equals(datetext.trim())) {
				return new Date();
			}
			if (format != null) {
				df = new SimpleDateFormat(format);
			} else {
				datetext = datetext.replaceAll("/", "-");
				df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			}
			return df.parse(datetext);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

//	public static String tryNorm(String input, String... formats) {
//		Date date = tryParse(input, formats);
//		return date == null ? null : format(date);
//	}
//
//	public static Date tryParse(String input, String... formats) {
//		if (formats == null || input == null)
//			return null;
//		// oprigin
//		for (String format : formats) {
//			Date date = parse(input, format);
//			if (date != null) {
//				return date;
//			}
//		}
//		input = StringUtil.normCnDate(input);
//		for (String format : formats) {
//			Date date = parse(input, format);
//			if (date != null) {
//				return date;
//			}
//		}
//		return null;
//	}
	
	
	
	public static void main(String args[]) {
		
		Date date1 = DateUtil.parse("2014-11-21 00:00:00");
		
		Date date2 = DateUtil.parse("2014-12-21 00:00:00");
		
		List<Date> dates = DateUtil.listDates(date1, date2);
		
		System.out.println(dates.size());
	}
}
